<?php
    // PDO封装的操作MySQL的工具类,叫做DB
    class DB {
        public $pdo = null;
        // 0. 构造函数调用连接
        public function __construct() {
            echo '连接数据库'.'<hr>';
            $this->ConnectDB();
        }
        // 1. 连接数据库
        public function ConnectDB() {
            try {
                $dsn = 'mysql:host=localhost;dbname=mysqldemo;charset=utf8';
                $user = 'root';
                $psw = '123456';
                $this->pdo = new PDO($dsn,$user,$psw, array(
                    PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
                ));
            } catch (PDOException $ex) {
                echo '数据库连接失败'.$ex->getMessage().'<hr>';
                die();  
            }
        }
        // 2. 关闭数据库
        public function CloseDB() {
            echo '关闭数据库'.'<hr>';
            $this->pdo = null;
        }
        
        // 析构函数-对象销毁的时候
        //  public function __destruct() {
        //      $this->CloseDB();
        //  }

        // 3. 执行SQL语句  返回影响行数/结果集
        // 全部使用预处理语句来执行
        public function query($sql, $param = null, $fetch_type = PDO::FETCH_ASSOC) {
            $stmt = $this->pdo->prepare($sql);
            if ($param && is_array($param)) {
                // 如果是索引数组,绑定  ?
                if(array_values($param) == $param) {
                    for ($k=1;$k<= count($param);$k++) {
                        echo '索引数组'.($k).'---'.$param[$k-1].'<hr>';
                        $stmt->bindParam($k, $param[$k-1]);
                    }
//                    $stmt->execute($param);
                } else {
                    echo '关联数组'.'<hr>';
                    // 如果是关联数字,绑定  名字
                    foreach ($param as $key => $value) {
                        $stmt->bindParam($key, $value);
                    }
                }
            }
            $stmt->execute();
            // 判断sql的类型    
            // 将sql语句按照空格分割
            $sql = trim($sql); //去除两端空格
            $sql_type = explode(' ', $sql)[0]; // 按照空格分割
            $sql_type = strtolower($sql_type); // 字符串转小写
            if ($sql_type == 'insert' || 
                    $sql_type == 'update' ||
                    $sql_type == 'delete'||
                    $sql_type == 'create') {
                return $stmt->rowCount();
            } else if ($sql_type == 'select' || 
                    $sql_type == 'show') {
                return $stmt->fetchAll($fetch_type);
            } 
        }
        // 4. 返回插入操作后的id
        public function lastID() {
            return $this->pdo->lastInsertId();
        }
        // 5. 事务
        // 5.1 开启事务
        public function beginTransaction() {
            $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0);
            $this->pdo->beginTransaction();
        }
        // 5.2 提交
        public function commitTransaction() {
            $this->pdo->commit();
            $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
        }
        // 5.3 回滚 
        public function rollBackTransaction() {
            $this->pdo->rollback();
            $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
        }
        
        
        // 测试以下"绑定栏目"
        public function  test() {
            $sql = 'select name from student';
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindColumn(1, $abc);
            $stmt->execute();
            
            while($stmt->fetch()) {
                echo $abc.'<hr>';
            }
            
        }
    }
